#pragma once

// 对epoll进行封装

#include <iostream>
#include <sys/epoll.h>

#include "Log.hpp"
#include "Common.hpp"

namespace EplollerModule
{
    using namespace LogMudule;
    class Eploller
    {
    public:
        Eploller()
        :_epoll_fd(-1)
        {}
        
        void Init()
        {
            // epoll_create 的返回值就是 epoll 句柄
            _epoll_fd = epoll_create(256);
            if(_epoll_fd < 0)
            {
                LOG(LogLevel::ERROR) << "epoll_create error";
                exit(EPOLL_ERR);
            }
            LOG(LogLevel::INFO) << "epoll_create success";
        }

        // epoll_event内核告诉用户-->fd可读/可写/异常
        int Wait(struct epoll_event revs[], int num, int timeout) // 输出就绪的fd和events
        {
            int n = epoll_wait(_epoll_fd, revs, num, timeout);
            if(n < 0)
            {
                LOG(LogLevel::ERROR) << "epoll_wait error";
                exit(EPOLL_ERR);
            }
            return n;
        }

        void Ctrl(int sockfd, uint32_t events)
        {
            struct epoll_event ev;
            ev.events = events;
            ev.data.fd = sockfd;
            int n = epoll_ctl(_epoll_fd, EPOLL_CTL_ADD, sockfd, &ev);
            if(n < 0)
            {
                LOG(LogLevel::ERROR) << "epoll_ctl error";
            }
        }

        ~Eploller();
    private:
        int _epoll_fd;
    };

}